// ============================================
// 11 - 泛型 (Generics)
// ============================================

/// 泛型是具体类型或其他属性的抽象替代
/// 可以减少代码重复，提高代码复用性

// ==================== 函数中的泛型 ====================

/// 泛型函数
pub fn generic_functions() {
    println!("\n=== 泛型函数 ===");
    
    // 找到 i32 切片中的最大值
    let number_list = vec![34, 50, 25, 100, 65];
    let result = largest_i32(&number_list);
    println!("最大的数字是 {}", result);
    
    // 找到 char 切片中的最大值
    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest_char(&char_list);
    println!("最大的字符是 {}", result);
    
    // 使用泛型函数
    let number_list = vec![34, 50, 25, 100, 65];
    let result = largest(&number_list);
    println!("使用泛型: 最大的数字是 {}", result);
    
    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("使用泛型: 最大的字符是 {}", result);
}

// 非泛型版本
fn largest_i32(list: &[i32]) -> &i32 {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

fn largest_char(list: &[char]) -> &char {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

// 泛型版本
fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

/// 多个泛型类型参数
pub fn multiple_type_parameters() {
    println!("\n=== 多个泛型类型 ===");
    
    let p1 = Point { x: 5, y: 10.4 };
    println!("点坐标: x = {}, y = {}", p1.x, p1.y);
    
    let p2 = Point { x: "Hello", y: 'c' };
    println!("点数据: x = {}, y = {}", p2.x, p2.y);
}

struct Point<T, U> {
    x: T,
    y: U,
}

// ==================== 结构体中的泛型 ====================

/// 结构体定义中的泛型
pub fn generic_structs() {
    println!("\n=== 泛型结构体 ===");
    
    let integer = PointSame { x: 5, y: 10 };
    let float = PointSame { x: 1.0, y: 4.0 };
    
    println!("整数点: x = {}, y = {}", integer.x, integer.y);
    println!("浮点点: x = {}, y = {}", float.x, float.y);
    
    // 混合类型
    let mixed = Point { x: 5, y: 4.0 };
    println!("混合点: x = {}, y = {}", mixed.x, mixed.y);
}

struct PointSame<T> {
    x: T,
    y: T,
}

// ==================== 枚举中的泛型 ====================

/// 枚举定义中的泛型
pub fn generic_enums() {
    println!("\n=== 泛型枚举 ===");
    
    // Option<T> 枚举
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;
    
    println!("Some number: {:?}", some_number);
    println!("Some string: {:?}", some_string);
    println!("Absent: {:?}", absent_number);
    
    // Result<T, E> 枚举
    let success: Result<i32, &str> = Ok(10);
    let failure: Result<i32, &str> = Err("出错了");
    
    println!("Success: {:?}", success);
    println!("Failure: {:?}", failure);
}

// ==================== 方法中的泛型 ====================

/// 为泛型结构体实现方法
impl<T> PointSame<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

// 为特定类型实现方法
impl PointSame<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

pub fn generic_methods() {
    println!("\n=== 泛型方法 ===");
    
    let p = PointSame { x: 5, y: 10 };
    println!("p.x = {}", p.x());
    
    let p = PointSame { x: 3.0, y: 4.0 };
    println!("距离原点: {}", p.distance_from_origin());
}

/// 方法中的混合泛型
impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

pub fn method_with_multiple_generics() {
    println!("\n=== 混合泛型方法 ===");
    
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };
    
    let p3 = p1.mixup(p2);
    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}

// ==================== 泛型性能 ====================

/// 泛型代码的性能
pub fn generic_performance() {
    println!("\n=== 泛型性能 ===");
    
    println!("Rust 使用单态化 (Monomorphization) 在编译时处理泛型");
    println!("编译器为每个具体类型生成专门的代码");
    println!("因此泛型代码的运行时性能与手写代码相同");
    println!("泛型不会带来运行时开销");
}

// ==================== const 泛型 ====================

/// const 泛型参数
pub fn const_generics() {
    println!("\n=== const 泛型 ===");
    
    struct ArrayPair<T, const N: usize> {
        left: [T; N],
        right: [T; N],
    }
    
    let arrays = ArrayPair {
        left: [1, 2, 3],
        right: [4, 5, 6],
    };
    
    println!("数组对创建成功");
    println!("左数组第一个元素: {}", arrays.left[0]);
    println!("右数组第一个元素: {}", arrays.right[0]);
}

// ==================== 泛型约束 ====================

/// trait 约束
pub fn trait_bounds() {
    println!("\n=== trait 约束 ===");
    
    fn print_it<T: std::fmt::Display>(item: T) {
        println!("打印: {}", item);
    }
    
    print_it(42);
    print_it("Hello");
    print_it(3.14);
    
    // 多个约束
    fn compare_and_print<T: std::fmt::Display + PartialOrd>(a: T, b: T) {
        if a > b {
            println!("{} > {}", a, b);
        } else {
            println!("{} <= {}", a, b);
        }
    }
    
    compare_and_print(5, 10);
    compare_and_print("hello", "world");
}

/// where 子句
pub fn where_clause() {
    println!("\n=== where 子句 ===");
    
    // 复杂的 trait 约束使用 where 更清晰
    fn some_function<T, U>(t: &T, u: &U) -> i32
    where
        T: std::fmt::Display + Clone,
        U: Clone + std::fmt::Debug,
    {
        println!("t: {}", t);
        println!("u: {:?}", u);
        42
    }
    
    let result = some_function(&"Hello", &vec![1, 2, 3]);
    println!("结果: {}", result);
}

// ==================== 实际应用示例 ====================

/// 泛型容器
#[derive(Debug)]
struct Container<T> {
    value: T,
}

impl<T> Container<T> {
    fn new(value: T) -> Self {
        Container { value }
    }
    
    fn get(&self) -> &T {
        &self.value
    }
    
    fn set(&mut self, value: T) {
        self.value = value;
    }
}

pub fn generic_container() {
    println!("\n=== 泛型容器 ===");
    
    let mut int_container = Container::new(42);
    println!("整数容器: {:?}", int_container);
    println!("值: {}", int_container.get());
    
    int_container.set(100);
    println!("更新后: {:?}", int_container);
    
    let string_container = Container::new(String::from("Hello"));
    println!("字符串容器: {:?}", string_container);
}

/// 泛型链表
#[derive(Debug)]
enum List<T> {
    Cons(T, Box<List<T>>),
    Nil,
}

pub fn generic_list() {
    println!("\n=== 泛型链表 ===");
    
    use List::{Cons, Nil};
    
    let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
    println!("整数链表: {:?}", list);
    
    let list = Cons("a", Box::new(Cons("b", Box::new(Cons("c", Box::new(Nil))))));
    println!("字符串链表: {:?}", list);
}

/// 泛型栈
#[derive(Debug)]
struct Stack<T> {
    items: Vec<T>,
}

impl<T> Stack<T> {
    fn new() -> Self {
        Stack { items: Vec::new() }
    }
    
    fn push(&mut self, item: T) {
        self.items.push(item);
    }
    
    fn pop(&mut self) -> Option<T> {
        self.items.pop()
    }
    
    fn is_empty(&self) -> bool {
        self.items.is_empty()
    }
    
    fn size(&self) -> usize {
        self.items.len()
    }
}

pub fn generic_stack() {
    println!("\n=== 泛型栈 ===");
    
    let mut stack = Stack::new();
    stack.push(1);
    stack.push(2);
    stack.push(3);
    
    println!("栈大小: {}", stack.size());
    
    while let Some(item) = stack.pop() {
        println!("弹出: {}", item);
    }
    
    println!("栈是否为空: {}", stack.is_empty());
}

/// 泛型对
#[derive(Debug)]
struct Pair<T, U> {
    first: T,
    second: U,
}

impl<T, U> Pair<T, U> {
    fn new(first: T, second: U) -> Self {
        Pair { first, second }
    }
    
    fn get_first(&self) -> &T {
        &self.first
    }
    
    fn get_second(&self) -> &U {
        &self.second
    }
}

pub fn generic_pair() {
    println!("\n=== 泛型对 ===");
    
    let pair1 = Pair::new(1, "one");
    println!("对1: {:?}", pair1);
    println!("第一个: {}, 第二个: {}", pair1.get_first(), pair1.get_second());
    
    let pair2 = Pair::new(String::from("hello"), 42);
    println!("对2: {:?}", pair2);
}

/// 泛型最佳实践
pub fn best_practices() {
    println!("\n=== 泛型最佳实践 ===");
    
    println!("1. 使用有意义的泛型参数名");
    println!("   - T: Type (类型)");
    println!("   - E: Error (错误)");
    println!("   - K: Key (键)");
    println!("   - V: Value (值)");
    println!("2. 添加必要的 trait 约束");
    println!("3. 使用 where 子句提高可读性");
    println!("4. 考虑使用 const 泛型");
    println!("5. 记住泛型没有运行时开销");
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust 泛型教程                        ║");
    println!("╚════════════════════════════════════════╝");
    
    generic_functions();
    multiple_type_parameters();
    generic_structs();
    generic_enums();
    generic_methods();
    method_with_multiple_generics();
    generic_performance();
    const_generics();
    trait_bounds();
    where_clause();
    generic_container();
    generic_list();
    generic_stack();
    generic_pair();
    best_practices();
    
    println!("\n✅ 泛型教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_largest() {
        let list = vec![34, 50, 25, 100, 65];
        assert_eq!(*largest(&list), 100);
    }
    
    #[test]
    fn test_container() {
        let mut container = Container::new(42);
        assert_eq!(*container.get(), 42);
        container.set(100);
        assert_eq!(*container.get(), 100);
    }
    
    #[test]
    fn test_stack() {
        let mut stack = Stack::new();
        stack.push(1);
        stack.push(2);
        assert_eq!(stack.size(), 2);
        assert_eq!(stack.pop(), Some(2));
        assert_eq!(stack.pop(), Some(1));
        assert!(stack.is_empty());
    }
}

